home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_5.7
/
XSGLL
/
LLPAR1.C
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
206 lines
/*
* llpar1.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/* PARALLELPAR: function takes start and end points of two parallel
* lines and returns distance between lines and overlap
* of lines
* usage: overlapFlag =
* parallelpar (ptO1, ptF1, ptO2, ptF2,
* &dist, &overlap12)
* OverlapFlag is 0 for no overlap, -1 for perpendicular
* lines (which is also no overlap), and 1 for overlap.
*
* HISTORY
* 4-Sept-85 Larry O'Gorman (log) at Bell Labs
* This is the umpteenth time the parameter calculation has
* been changed, and I'm getting a little tired of doing so.
*
* 26-Apr-85 Larry O'Gorman (log) at Bell Labs
* Created.
*/
#include <math.h>
#include <stdlib.h>
#include "lldef.h"
#include "sal.h"
#define OVERLAP 1 /* overlap exists */
#define NOOVERLAP 0 /* no overlap exists */
#define PERPENDICULAR -1 /* no nothing: lines are perpend. */
int
parallelpar (ptO1, ptF1, ptO2, ptF2, dist, overlap)
struct point ptO1, /* initial and final pts of line 1 */
ptF1, ptO2, /* initial and final pts of line 2 */
ptF2;
double *dist, /* perpendic. dist. between lines */
*overlap; /* overlap between line segments */
{
register double deltaX1, /* run and rise of line 1 slope */
deltaY1, deltaX2, /* run and rise of line 2 slope */
deltaY2;
struct { /* points on line 2 */
double x, y;
} pnts[4], midpt[2];
double xO1, /* initial (O) and final (F) */
yO1, /* points of lines 1 and 2 */
xF1, yF1, xO2, yO2, xF2, yF2, xA2, /* intersection pts of perp. on line 2 */
yA2, xB2, yB2, xM2, /* middle point of second line */
yM2, max, /* max/min of 4 points on line 2 */
min, numer, /* numerator and denominator */
denom, /* of distance calculation */
overlap2, /* absolute overlap on line 2 */
length2, /* lenght of line 2 */
temp;
register long maxI, /* for ordering points */
minI, i, j;
int defined; /* 1 = overlap; 0 = none */
/* initialize */
xO1 = (double) ptO1.x;
yO1 = (double) ptO1.y;
xF1 = (double) ptF1.x;
yF1 = (double) ptF1.y;
xO2 = (double) ptO2.x;
yO2 = (double) ptO2.y;
xF2 = (double) ptF2.x;
yF2 = (double) ptF2.y;
deltaX1 = xF1 - xO1;
deltaY1 = yF1 - yO1;
deltaX2 = xF2 - xO2;
deltaY2 = yF2 - yO2;
/* intersection of perpendiculars from ends of line 1 to line 2 */
temp = (deltaY2 * deltaY1 + deltaX1 * deltaX2);
if (temp == 0.0)
return (PERPENDICULAR);
if (deltaX2 != 0.0) {
xA2 = (1.0 / temp)
* (xO1 * deltaX2 * deltaX1 + xO2 * deltaY2 * deltaY1
+ deltaX2 * deltaY1 * (yO1 - yO2));
yA2 = (deltaY2 / deltaX2) * (xA2 - xO2) + yO2;
xB2 = (1.0 / temp)
* (xF1 * deltaX2 * deltaX1 + xO2 * deltaY2 * deltaY1
+ deltaX2 * deltaY1 * (yF1 - yO2));
yB2 = (deltaY2 / deltaX2) * (xB2 - xO2) + yO2;
}
else {
yA2 = (1.0 / temp)
* (yO1 * deltaY2 * deltaY1 + yO2 * deltaX2 * deltaX1
+ deltaY2 * deltaX1 * (xO1 - xO2));
xA2 = (deltaX2 / deltaY2) * (yA2 - yO2) + xO2;
yB2 = (1.0 / temp)
* (yF1 * deltaY2 * deltaY1 + yO2 * deltaX2 * deltaX1
+ deltaY2 * deltaX1 * (xF1 - xO2));
xB2 = (deltaX2 / deltaY2) * (yB2 - yO2) + xO2;
}
/* test if intersection points fall outside of line segment 2 */
/* if it does, set defined flag to indicate no overlap, BUT continue
* with calculations to find direction of line 1 to 2 */
defined = OVERLAP;
if (deltaX2 != 0.0) {
if (xA2 >= xO2 && xA2 >= xF2 && xB2 >= xO2 && xB2 >= xF2)
defined = NOOVERLAP;
else if (xA2 <= xO2 && xA2 <= xF2 && xB2 <= xO2 && xB2 <= xF2)
defined = NOOVERLAP;
}
else {
if (yA2 >= yO2 && yA2 >= yF2 && yB2 >= yO2 && yB2 >= yF2)
defined = NOOVERLAP;
else if (yA2 <= yO2 && yA2 <= yF2 && yB2 <= yO2 && yB2 <= yF2)
defined = NOOVERLAP;
}
/* find the middle 2 pnts of overlap (or of no overlap, if none) on line 2 */
pnts[0].x = xO2;
pnts[0].y = yO2;
pnts[1].x = xF2;
pnts[1].y = yF2;
pnts[2].x = xA2;
pnts[2].y = yA2;
pnts[3].x = xB2;
pnts[3].y = yB2;
if (deltaX2 == 0.0) {
max = min = pnts[0].y;
maxI = minI = 0;
for (i = 1; i < 4; i++) {
if (pnts[i].y > max) {
maxI = i;
max = pnts[i].y;
}
else if (pnts[i].y < min) {
minI = i;
min = pnts[i].y;
}
}
}
else {
max = min = pnts[0].x;
maxI = minI = 0;
for (i = 1; i < 4; i++) {
if (pnts[i].x > max) {
maxI = i;
max = pnts[i].x;
}
else if (pnts[i].x < min) {
minI = i;
min = pnts[i].x;
}
}
}
for (i = 0, j = 0; i < 4; i++) {
if (i != minI && i != maxI) {
midpt[j].x = pnts[i].x;
midpt[j].y = pnts[i].y;
j++;
}
}
/* find dist from line 1 to midpt. of overlap segment on line 2 */
xM2 = (midpt[0].x + midpt[1].x) / 2.0;
yM2 = (midpt[0].y + midpt[1].y) / 2.0;
if (deltaX1 == 0.0)
*dist = xM2 - xO1;
else if (deltaY1 == 0.0)
*dist = yM2 - yO1;
else {
numer = (xM2 - xO1) - (yM2 - yO1) * deltaX1 / deltaY1;
denom = sqrt ((deltaX1 * deltaX1) / (deltaY1 * deltaY1) + 1.0);
*dist = numer / denom;
}
/* calculate overlap */
overlap2 = (midpt[0].x - midpt[1].x) * (midpt[0].x - midpt[1].x)
+ (midpt[0].y - midpt[1].y) * (midpt[0].y - midpt[1].y);
length2 = (xO2 - xF2) * (xO2 - xF2) + (yO2 - yF2) * (yO2 - yF2);
*overlap = sqrt ((overlap2 / length2)) * 100.0;
return (defined);
}